#include "PlaylistWidget.h"

#define MAX(a, b) (((a) > (b)) ? (a) : (b))

/*---------------------------------------------------------------------------------------
--	FUNCTION:	PlaylistWidget::PlaylistWidget(Playlist * thePlaylist,
                               PlaylistClient * client) : QTableWidget(0, 3),
                                                          playlist(thePlaylist),
                                                          playlistClient(client)
--
--	DATE:			April 07, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Ribeiro
--
--	PROGRAMMER:		Eric Ribeiro
--
--	RETURNS:
--
--	NOTES:
--		Constructor for the PlaylistWidget
----------------------------------------------------------------------------------------*/
PlaylistWidget::PlaylistWidget(Playlist * thePlaylist,
                               PlaylistClient * client) : QTableWidget(0, 3),
                                                          playlist(thePlaylist),
                                                          playlistClient(client)
{
    QStringList headers;

    headers << "" << "Song" << "Votes";

    setHorizontalHeaderLabels(headers);
    setAlternatingRowColors(true);

    verticalHeader()->hide();
    horizontalHeader()->resizeSection(0, 25);
    horizontalHeader()->setResizeMode(0, QHeaderView::Fixed);
    horizontalHeader()->setResizeMode(1, QHeaderView::Stretch);

    playlist->addObserver(this);
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	PlaylistWidget::notify (Observable * obj, int eventCode)
--
--	DATE:			April 07, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Ribeiro
--
--	PROGRAMMER:		Eric Ribeiro
--
--	RETURNS:
--
--	NOTES:
--		Function to notify the the observable object with specific event code
----------------------------------------------------------------------------------------*/
void PlaylistWidget::notify (Observable * obj, int eventCode)
{
    if (obj == playlist)
    {
        switch (eventCode)
        {
        case Playlist::SongRemoved:
            QMetaObject::invokeMethod(this, "songRemoved", Qt::QueuedConnection);
            break;

        case Playlist::SongAdded:
            QMetaObject::invokeMethod(this, "songAdded", Qt::QueuedConnection);
            break;

        case Playlist::VotesChanged:
            QMetaObject::invokeMethod(this, "votesChanged", Qt::QueuedConnection);
            break;

        case Playlist::NowPlayingChanged:
            QMetaObject::invokeMethod(this, "nowPlayingChanged", Qt::QueuedConnection);
            break;
        }
    }
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	PlaylistWidget::songAdded ()
--
--	DATE:			April 07, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Ribeiro
--
--	PROGRAMMER:		Eric Ribeiro
--
--	RETURNS:
--
--	NOTES:
--		Function to update the name of the song on the GUI
----------------------------------------------------------------------------------------*/
void PlaylistWidget::songAdded ()
{
    std::list<Song *> songList = playlist->copySongList();
    std::list<Song *>::reverse_iterator it = songList.rbegin();

    int previousRowCount = rowCount();
    setRowCount(songList.size());

    for (int nextRow = songList.size() - 1; nextRow >= previousRowCount; nextRow--)
    {
        std::string fileName = (*it)->getFilename();
        QTableWidgetItem * fileNameItem = new QTableWidgetItem(QString::fromStdString(fileName));

        setItem(nextRow, 1, fileNameItem);
        setCellWidget(nextRow, 2, new PlaylistVoteWidget((*it), playlist, playlistClient));

        it++;
    }
}

/*---------------------------------------------------------------------------------------
--	FUNCTION:	PlaylistWidget::songRemoved ()
--
--	DATE:			April 07, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Ribeiro
--
--	PROGRAMMER:		Eric Ribeiro
--
--	RETURNS:
--
--	NOTES:
--		Function to remove the name of the song from the list on the GUI
----------------------------------------------------------------------------------------*/
void PlaylistWidget::songRemoved ()
{
    std::list<Song *>::iterator it;
    std::list<Song *> songList = playlist->copySongList();

    for (int i = 0; i < rowCount(); i++)
    {
        std::string fileName = item(i, 1)->text().toStdString();

        for (it = songList.begin(); it != songList.end(); it++)
        {
            if ((*it)->getFilename().compare(fileName) == 0)
                break;

            if (++it == songList.end())
                removeRow(i);

            --it;
        }
    }
}
/*---------------------------------------------------------------------------------------
--	FUNCTION:	PlaylistWidget::votesChanged ()
--
--	DATE:			April 07, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Ribeiro
--
--	PROGRAMMER:		Eric Ribeiro
--
--	RETURNS:
--
--	NOTES:
--		Function to udate the votes when it gets called
----------------------------------------------------------------------------------------*/
void PlaylistWidget::votesChanged ()
{
    for (int i = 0; i < rowCount(); i++)
    {
        PlaylistVoteWidget * voteWidget = (PlaylistVoteWidget*)cellWidget(i, 2);

        if (voteWidget != 0)
        {
            voteWidget->updateVotes();
        }
    }
}
/*---------------------------------------------------------------------------------------
--	FUNCTION:	PlaylistWidget::votesChanged ()
--
--	DATE:			April 07, 2010
--
--	REVISIONS		(Date and Description):
--
--	DESIGNER:		Eric Ribeiro
--
--	PROGRAMMER:		Eric Ribeiro
--
--	RETURNS:
--
--	NOTES:
--		Function to when the currently playing song gets changed
----------------------------------------------------------------------------------------*/
void PlaylistWidget::nowPlayingChanged ()
{
    Song * nowPlaying = playlist->getPlaying();

    if (nowPlaying == 0)
        return;

    std::string songFileName = nowPlaying->getFilename();

    for (int i = 0; i < rowCount(); i++)
    {
        QTableWidgetItem * currentItem = item(i, 1);

        if (currentItem == 0)
            continue;

        std::string fileName = currentItem->text().toStdString();

        if (songFileName.compare(fileName) == 0)
        {
            QTableWidgetItem * nowPlayingItem = new QTableWidgetItem();
            nowPlayingItem->setIcon(QIcon(":/Resources/Images/Playing.png"));
            setItem(i, 0, nowPlayingItem);
        }
        else
        {
            setItem(i, 0, 0);
        }
    }
}
